using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;

namespace CSharpXDL
{
    internal class BlockDownloader : XRun
    {
        String url;
        internal char fName;
        internal long total, partial, readed;
        bool completed = false;
       
        bool reStart = false;
        DownLoad downloader;
        static int blockL = 10;//1024 * 2;

        Stream channel;
        Stream responseStream;
        BinaryReader binReader;
        XDLConnect myHttpWebResponse;
        public BlockDownloader(DownLoad downloader, String url, char fName, long partial, long total)
        {
            this.downloader = downloader;
            this.fName = fName;
            this.url = url;
            this.partial = partial;
            this.total = total;
            
            this.channel = downloader.Channel;
            readed = downloader.getBpr(fName);
        }
    
        public void run() {
		int count = 0;
		aging: while (count < 100) {
			
			try {
				if (count > 0)
                    Console.WriteLine(fName + " reStart. ");
				long unReadLen= total- readed;
//				System.out.println(fName+" "+total+" "+unReadLen+" "+ file.length());
				if (unReadLen <= 0) {
					completed = true;
					downloader.complete(fName);
					return;
				}
                myHttpWebResponse = ConnectHelper.GetXDLConnect(url, partial + readed);
                
                int responseCode =(int) myHttpWebResponse.GetStateCode();
                if (responseCode > 499) throw new Exception("net connect Error ResponseCode " + myHttpWebResponse.GetStatusDescription());

                binReader = myHttpWebResponse.GetResponseStream();

             //   Console.WriteLine(fName + " start time:" + DateTime.Now.ToLocalTime() + " " + myHttpWebResponse.stream.DataAvailable);
				long position =0;
				
				long len = 0;
				int allocate=unReadLen>=blockL?blockL:(int)unReadLen;
          
				
				while ( unReadLen>0) {
                  // int ooo= binReader.ReadByte();
                    byte[] buffer= binReader.ReadBytes(allocate);

                    len = buffer.Length;
                    if (buffer.Length == 0 && unReadLen > 0)
                    {

                      // myHttpWebResponse. stream.
						try {
                            myHttpWebResponse.Close();
							
						} catch (Exception e) {
                          
						}
						count++;
						goto aging;
					}
                    if (readed == 0)
                    {



                    }
					position = partial+readed;
					unReadLen -= len;
            
                    downloader.Write(position,buffer);
			
					readed+=len;
                    allocate = unReadLen >= blockL ? blockL :(int) unReadLen;
				}
				
				completed = true;
				downloader.complete(fName);
                myHttpWebResponse.Close();
				return;
			} catch (Exception e) {
                Console.WriteLine(e.StackTrace);
				try {
                    
                    if (myHttpWebResponse != null)
                    {
                        myHttpWebResponse.Close();
					}


                    //Thread.Sleep(5000);
				} catch (Exception e1) {

                    Console.WriteLine(e1.StackTrace);
				}
				 Console.WriteLine(fName +" "+e.Message+ " Exception time:"
						+ DateTime.Now.ToLocalTime());
				count++;
				continue ;
			}
		}

	}

        public long length()
        {
            return readed;
        }
    }
}
